package crond

import (
	"context"
	"fmt"
	"strconv"
	"strings"
	"time"

	"sale-admin/config"

	"sale-admin/config/mysql"
	"sale-admin/internal/app/grpc/client"
	"sale-admin/internal/app/grpc/protoc/devicec"
	"sale-admin/internal/app/grpc/protoc/system_admin"
	"sale-admin/internal/app/web/service/common"
	"sale-admin/internal/app/web/service/robotinfo"
	"sale-admin/internal/dal"
	"sale-admin/internal/dao"
	"sale-admin/internal/models"

	"192.168.1.75/go-pkg/helper"
	"192.168.1.75/go-pkg/logx"
	"github.com/golang-module/carbon/v2"
	"github.com/samber/lo"
	"github.com/xuri/excelize/v2"
	"gorm.io/datatypes"
)

// 保存订单记录
type OrderReportStruct struct {
	MerchantID        string  `json:"merchant_id"`
	UserName          string  `gorm:"-" json:"user_name"`
	SalesID           string  `json:"sales_id"`
	OrderStatus       int     `json:"order_status"`
	RobotName         string  `json:"robot_name"`
	Areas3            string  `json:"areas3"`
	Areas3Name        string  `json:"areas3_name"`
	Gmv               float64 `json:"gmv"`
	PaymentAmount     float64 `json:"payment_amount"`
	RefundOrderCount  float64 `json:"refund_order_count"`
	RefundOrderAmount float64 `json:"refund_order_amount"`
	StartOrderCount   float64 `json:"start_order_count"`
	SuccessOrderCount float64 `json:"success_order_count"`
	NotPayOrderCount  float64 `json:"not_pay_order_count"`
	FaceCount         float64 `json:"facecount"`
	FaceCount0        float64 `json:"facecount0"`
	FaceCount1        float64 `json:"facecount1"`
	FaceCount2        float64 `json:"facecount2"`
	FaceCount3        float64 `json:"facecount3"`
	ClickNum          float64 `json:"click_num"`
	PayNum            float64 `json:"pay_num"`
	OpeningFlag       string  `json:"opening_flag"`
	OpeningTime       string  `json:"opening_time"`
}

type SalesIDEventList struct {
	SalesID          string  `json:"sales_id"`
	RobotName        string  `json:"robot_name"`
	EventCount       int64   `json:"event_count"`
	MoveCount        int64   `json:"move_count"`
	EmergencyCount   int64   `json:"emergency_count"`
	AffectedTimeMill float64 `json:"affected_time_mill"`
}
type SalesIDSalesInfoList struct {
	RobotName              string `json:"robot_name"`
	SalesID                string `json:"sales_id"`
	TotalGoodsInventory    int64  `json:"total_goods_inventory"`
	TotalGoodsMaxInventory int64  `json:"total_goods_max_inventory"`
}

type TaskStruct struct {
	TotalTaskOdometer       int64
	TotalTaskDuration       int64
	TotalTaskRunCount       int64
	TotalChargingDuration   int64
	TotalIdleDuration       int64
	TotalToChargingDuration int64
	TotalToTaskDuration     int64
	TotalFaultDuration      int64
}

type EmptyStockStruct struct {
	models.MaRobotEmptyStock
	ProvinceID string `gorm:"-" json:"province_id"`
	CityID     string `gorm:"-" json:"city_id"`
}

type EmptyWeeklyReport struct {
	RobotName  string  `json:"robot_name"`
	GoodsName  string  `json:"goods_name"`
	ProvinceID string  `json:"province_id"`
	Province   string  `json:"province"`
	CityID     string  `json:"city_id"`
	City       string  `json:"city"`
	LocationID string  `json:"location_id"`
	Location   string  `json:"location"`
	Monday     int     `json:"monday"`
	Tuesday    int     `json:"tuesday"`
	Wednesday  int     `json:"wednesday"`
	Thursday   int     `json:"thursday"`
	Friday     int     `json:"friday"`
	Saturday   int     `json:"saturday"`
	Sunday     int     `json:"sunday"`
	EmptyTotal int     `json:"empty_total"`
	EmptyRate  float64 `json:"empty_rate"`
}

func GetRobotConfigDetail(ID string) (RobotList, MerchantList []string, err error) {
	configInfo, count, _ := dao.RobotReportConfig{}.Detail(context.Background(), dal.Q, "", ID, 0)
	if count == 0 {
		return
	}
	SystemAdminClient, clientErr := client.GetSystemAdminClient()
	if clientErr != nil {
		err = clientErr
		return
	}
	if configInfo.RobotSelectType == 1 { // 商户所属机器
		if configInfo.Object != "" && configInfo.Object != "1" {
			// 获取直系商户
			req := &system_admin.FamilyMerchantsReq{
				MerchantId: configInfo.Object,
			}
			rsp, err1 := SystemAdminClient.GetFamilyMerchants(context.Background(), req)
			if err1 != nil {
				return
			}
			robots, robotCount, _ := dao.Robot{}.RobotList(context.Background(), mysql.NewDB(),
				strings.Join(rsp.MerchantIds, ","), "", "", "", "", "", "", "")
			if robotCount == 0 {
				return
			}
			for _, robot := range robots {
				RobotList = append(RobotList, robot.RobotName)
			}
			MerchantList = append(MerchantList, rsp.MerchantIds...)
		}
	} else if configInfo.RobotSelectType == 2 { // 指定机器
		RobotList = strings.Split(configInfo.RobotName, ",")
	} else if configInfo.RobotSelectType == 3 { // 指定商户
		MerchantSelectList := strings.Split(configInfo.MerchantSelect, ",")
		if len(strings.Split(configInfo.MerchantSelect, ",")) == 0 {
			return
		}
		for _, merchantID := range MerchantSelectList {
			req := &system_admin.FamilyMerchantsReq{
				MerchantId: merchantID,
			}
			rsp, err1 := SystemAdminClient.GetFamilyMerchants(context.Background(), req)
			if err1 != nil {
				return
			}
			MerchantList = append(MerchantList, rsp.MerchantIds...)
		}
		robots, robotCount, _ := dao.Robot{}.RobotList(context.Background(), mysql.NewDB(),
			strings.Join(MerchantList, ","), "", "", "", "", "", "", "")
		if robotCount == 0 {
			return
		}
		for _, robot := range robots {
			RobotList = append(RobotList, robot.RobotName)
		}
	}
	return
}

// 空货报告
func SaveEmptyStock() (err error) {
	// GRPC获取设备区域信息
	LocationMap := make(map[string]string)
	ProvinceMap := make(map[string]string)
	CityMap := make(map[string]string)
	areaIDList := []string{}
	deviceClient, clientErr := client.GetDeviceAdminClient()
	if clientErr != nil {
		err = clientErr
		return
	}
	{
		deviceReq := &devicec.LocationListReq{}
		deviceRes, err := deviceClient.LocationList(context.Background(), deviceReq)
		if deviceRes != nil && deviceRes.Code == 0 && err == nil {
			for _, v := range deviceRes.List {
				LocationMap[v.Id] = v.Name
				ProvinceMap[v.Id] = v.ProvinceId
				CityMap[v.Id] = v.CityId
				areaIDList = append(areaIDList, v.ProvinceId)
				areaIDList = append(areaIDList, v.CityId)
			}
		}
	}

	SystemAdminClient, clientErr := client.GetSystemAdminClient()
	if clientErr != nil {
		err = clientErr
		return
	}
	// GRPC获取省市区名称
	AreaNameMap := make(map[string]string)
	{
		req := system_admin.AreaLisRequest{}
		req.AreaIDs = areaIDList
		res, err1 := SystemAdminClient.AreaList(context.Background(), &req)
		if err1 != nil {
			logx.Error(context.Background(), "areas error", logx.Any("res", res), logx.Any("err", err1.Error()))
			return nil
		}
		for _, v := range res.Areas {
			AreaNameMap[v.ID] = v.Name
		}
	}

	today := carbon.Now().ToDateString() // 今日
	// 今日空货的货道
	db := mysql.NewDB()
	data, _, _ := dao.RobotSalesInfo{}.GetEmptyStockList(context.Background(), dal.Q)
	var TodayEmptyStockGoods = make(map[string]string) // robot_name + "_" + goods_id
	for _, v := range data {
		if v.LocationID != "0" && v.LocationID != "" && v.RobotName != "" && v.MerchantID != "" {
			goodsID, _ := strconv.ParseInt(v.GoodsID, 10, 64)
			// 写入单日空货
			dao.RobotEmptyStock{}.Create(context.Background(), dal.Q, 1, /* 1-单日空货 */
				v.MerchantID, v.RobotName, today, goodsID, v.GoodsName1, int64(v.RobotGoodsInventory),
				int64(v.GoodsMaxInventory), v.LocationID)

			robotGoods := v.RobotName + "_" + v.GoodsID
			TodayEmptyStockGoods[robotGoods] = robotGoods
		}
	}

	// 单日空货查询报告配置
	RobotConfigList, _, _ := dao.RobotReportConfig{}.List(context.Background(), dal.Q, "", "", 2, 0, 0) // 2 单日空货
	if len(RobotConfigList) > 0 {
		for _, v := range RobotConfigList {
			ConfigRobotList, MerchantList, _ := GetRobotConfigDetail(v.ID)
			todayEmptyStock := []EmptyStockStruct{}
			if len(MerchantList) > 0 {
				// 查询当天的单日空货
				db.Model(&models.MaRobotEmptyStock{}).
					Where("merchant_id IN (?)", MerchantList).
					Where("date = ?", today).
					Where("type = 1").
					Find(&todayEmptyStock)
			} else if len(ConfigRobotList) > 0 {
				// 查询当天的单日空货
				db.Model(&models.MaRobotEmptyStock{}).
					Where("robot_name IN (?)", ConfigRobotList).
					Where("date = ?", today).
					Where("type = 1").
					Find(&todayEmptyStock)
			}
			if len(todayEmptyStock) > 0 {
				for k, v := range todayEmptyStock {
					if locationName, ok := LocationMap[v.LocationID]; ok {
						if _, ok := AreaNameMap[ProvinceMap[v.LocationID]]; ok {
							v.ProvinceID = AreaNameMap[v.ProvinceID] // 省名称
						}
						if _, ok := AreaNameMap[CityMap[v.LocationID]]; ok {
							v.CityID = AreaNameMap[CityMap[v.LocationID]] // 市名称
						}
						v.LocationID = locationName // 商场名称
						todayEmptyStock[k] = v
					}
				}

				// 生成excel,保存到文件目录
				excelURL := CreateEmptyStockExcel(todayEmptyStock, 1)
				err1 := dao.RobotReportLog{}.Create(context.Background(), dal.Q, excelURL, 4, /*单日空货*/
					strings.Join(ConfigRobotList, ","), v.ObjectName, v.WebHookName, v.WebHookAddress, v.Object,
					v.Object, time.Now(), time.Now())
				if err1 == nil {
					// 推送到飞书群聊
					statusCode, _, err := helper.Net{}.Request(context.Background(), "POST", v.WebHookAddress, nil,
						map[string]interface{}{
							"msg_type": "text",
							"content": map[string]interface{}{
								"text": excelURL,
							},
						},
					)
					if statusCode != 200 || err != nil {
						logx.Error(context.Background(), "单日空货推送error", logx.Any("statusCode", statusCode), logx.Any("error", err))
					} else {
						logx.Error(context.Background(), "单日空货推送success", logx.Any("statusCode", statusCode), logx.Any("error", err))
					}
				} else {
					logx.Error(context.Background(), "单日空货log写入error")
				}
			}
		}
	}

	// 连续空货查询报告配置
	RobotConfigList, _, _ = dao.RobotReportConfig{}.List(context.Background(), dal.Q, "", "", 3, 0, 0) // 3 连续空货
	for _, v := range RobotConfigList {
		ConfigRobotList, MerchantList, _ := GetRobotConfigDetail(v.ID)
		yesterDayEmptyStock := []EmptyStockStruct{}
		yesterday := carbon.Yesterday().ToDateString() // 昨日
		intersectData := []EmptyStockStruct{}
		if len(MerchantList) > 0 {
			db.Model(&models.MaRobotEmptyStock{}).
				Where("merchant_id IN (?)", MerchantList).
				Where("date = ?", yesterday).
				Where("type = 1").
				Find(&yesterDayEmptyStock)
		} else if len(ConfigRobotList) > 0 {
			db.Model(&models.MaRobotEmptyStock{}).
				Where("robot_name IN (?)", ConfigRobotList).
				Where("date = ?", yesterday).
				Where("type = 1").
				Find(&yesterDayEmptyStock)
		}
		if len(yesterDayEmptyStock) == 0 {
			continue
		}
		// 取今日与昨日的交集
		for _, val := range yesterDayEmptyStock {
			if _, ok := TodayEmptyStockGoods[val.RobotName+"_"+strconv.FormatInt(val.GoodsID, 10)]; ok {
				intersectData = append(intersectData, val)
			}
		}

		if len(intersectData) > 0 {
			for ik, iv := range intersectData {
				// 写入连续空货
				if iv.LocationID != "0" && iv.LocationID != "" && iv.RobotName != "" && iv.MerchantID != "" {
					dao.RobotEmptyStock{}.Create(context.Background(), dal.Q, 2, /* 2-连续空货 */
						iv.MerchantID, iv.RobotName, today, iv.GoodsID, iv.GoodsName1,
						iv.GoodsInventory, int64(iv.GoodsMaxInventory), iv.LocationID)
				}
				if locationName, ok := LocationMap[iv.LocationID]; ok {
					if _, ok := AreaNameMap[ProvinceMap[iv.LocationID]]; ok {
						iv.ProvinceID = AreaNameMap[iv.ProvinceID] // 省名称
					}
					if _, ok := AreaNameMap[CityMap[iv.LocationID]]; ok {
						iv.CityID = AreaNameMap[CityMap[iv.LocationID]] // 市名称
					}
					iv.LocationID = locationName // 商场名称
					intersectData[ik] = iv
				}
			}

			// 生成excel,保存到文件目录
			excelURL := CreateEmptyStockExcel(intersectData, 2)
			// 生成连续空货记录
			err1 := dao.RobotReportLog{}.Create(context.Background(), dal.Q, excelURL, 5, /*连续空货*/
				strings.Join(ConfigRobotList, ","), v.ObjectName, v.WebHookName, v.WebHookAddress, v.Object,
				v.Object, time.Now(), time.Now())
			if err1 == nil {
				// 推送到飞书群聊
				statusCode, _, err := helper.Net{}.Request(context.Background(), "POST", v.WebHookAddress, nil,
					map[string]interface{}{
						"msg_type": "text",
						"content": map[string]interface{}{
							"text": excelURL,
						},
					},
				)
				if statusCode != 200 || err != nil {
					logx.Error(context.Background(), "连续空货推送error", logx.Any("statusCode", statusCode), logx.Any("error", err))
				} else {
					logx.Error(context.Background(), "连续空货推送success", logx.Any("statusCode", statusCode), logx.Any("error", err))
				}
			} else {
				logx.Error(context.Background(), "连续空货log写入error")
			}
		}
	}
	// 空货周报 【机器-商品 上周七天的空货情况0非空1空，计算空货率】
	if carbon.Now().IsMonday() {
		Monday := carbon.Now().SubDays(7).ToDateString()
		Tuesday := carbon.Now().SubDays(6).ToDateString()
		Wednesday := carbon.Now().SubDays(5).ToDateString()
		Thursday := carbon.Now().SubDays(4).ToDateString()
		Friday := carbon.Now().SubDays(3).ToDateString()
		Saturday := carbon.Now().SubDays(2).ToDateString()
		Sunday := carbon.Now().SubDays(1).ToDateString()
		// 空货周报查询报告配置
		RobotConfigList, _, _ = dao.RobotReportConfig{}.List(context.Background(), dal.Q, "", "", 5, 0, 0) // 5 空货周报
		for _, v := range RobotConfigList {
			ConfigRobotList, _, _ := GetRobotConfigDetail(v.ID)
			if len(ConfigRobotList) > 0 {
				// 设备上的所有商品
				var RobotGoods []struct {
					RobotName string `json:"robot_name"`
					GoodsID   string `json:"goods_id"`
				}
				db.Model(&models.MaRobotSalesInfo{}).
					Where("robot_name in (?)", ConfigRobotList).
					Select("robot_name, goods_id").
					Group("robot_name, goods_id").
					Find(&RobotGoods)
				GoodsIDs := []string{}
				for _, i := range RobotGoods {
					GoodsIDs = append(GoodsIDs, i.GoodsID)
				}
				GoodsIDs = lo.Uniq(GoodsIDs)
				goodsMap := dao.Goods{}.DetailMap(context.Background(), dal.Q, GoodsIDs)
				// 上周所有空货商品
				var RobotEmptyStock []models.MaRobotEmptyStock
				db.Model(&models.MaRobotEmptyStock{}).
					Where("date between ? and ?", Monday, Sunday).
					Where("type = 1").
					Find(&RobotEmptyStock)
				var RobotEmptyStockMap = make(map[string][]string) // 日期 => []{机器+"_"+商品id}
				for _, i := range RobotEmptyStock {
					RobotEmptyStockMap[i.Date] = append(RobotEmptyStockMap[i.Date], i.RobotName+"_"+strconv.FormatInt(i.GoodsID, 10))
				}
				var ExcelData []EmptyWeeklyReport
				for _, i := range RobotGoods {
					robotInfo, robotError := dao.Robot{}.RobotDetail(context.Background(), db, "", i.RobotName, "")
					if robotError != nil || robotInfo == nil || robotInfo.MerchantID == "" {
						continue
					}
					var item EmptyWeeklyReport
					if goods, ok := goodsMap[i.GoodsID]; ok {
						item.GoodsName = goods.GoodsName1
					}
					item.RobotName = i.RobotName
					if locationName, ok := LocationMap[strconv.Itoa(robotInfo.Areas3)]; ok {
						item.Location = locationName // 商场名称
						if _, ok := AreaNameMap[strconv.Itoa(robotInfo.Areas1)]; ok {
							item.Province = AreaNameMap[strconv.Itoa(robotInfo.Areas1)] // 省名称
						}
						if _, ok := AreaNameMap[strconv.Itoa(robotInfo.Areas2)]; ok {
							item.City = AreaNameMap[strconv.Itoa(robotInfo.Areas2)] // 市名称
						}
					}
					//【设备+商品】在某个【日期】是否空货
					if mondayEmptyStock, ok := RobotEmptyStockMap[Monday]; ok {
						if lo.Contains(mondayEmptyStock, i.RobotName+"_"+i.GoodsID) {
							item.Monday = 1
						}
					}
					if tuesdayEmptyStock, ok := RobotEmptyStockMap[Tuesday]; ok {
						if lo.Contains(tuesdayEmptyStock, i.RobotName+"_"+i.GoodsID) {
							item.Tuesday = 1
						}
					}
					if wednesdayEmptyStock, ok := RobotEmptyStockMap[Wednesday]; ok {
						if lo.Contains(wednesdayEmptyStock, i.RobotName+"_"+i.GoodsID) {
							item.Wednesday = 1
						}
					}
					if thursdayEmptyStock, ok := RobotEmptyStockMap[Thursday]; ok {
						if lo.Contains(thursdayEmptyStock, i.RobotName+"_"+i.GoodsID) {
							item.Thursday = 1
						}
					}
					if fridayEmptyStock, ok := RobotEmptyStockMap[Friday]; ok {
						if lo.Contains(fridayEmptyStock, i.RobotName+"_"+i.GoodsID) {
							item.Friday = 1
						}
					}
					if saturdayEmptyStock, ok := RobotEmptyStockMap[Saturday]; ok {
						if lo.Contains(saturdayEmptyStock, i.RobotName+"_"+i.GoodsID) {
							item.Saturday = 1
						}
					}
					if sundayEmptyStock, ok := RobotEmptyStockMap[Sunday]; ok {
						if lo.Contains(sundayEmptyStock, i.RobotName+"_"+i.GoodsID) {
							item.Sunday = 1
						}
					}
					item.EmptyTotal = item.Monday + item.Tuesday + item.Wednesday + item.Thursday + item.Friday + item.Saturday + item.Sunday
					item.EmptyRate = common.Decimal(float64(item.EmptyTotal)/7, 4)
					ExcelData = append(ExcelData, item)
				}
				// 写入excel
				excelURL := CreateWeekEmptyStockExcel(ExcelData)
				// 生成连续空货记录
				err1 := dao.RobotReportLog{}.Create(context.Background(), dal.Q, excelURL, 6, /*空货周报*/
					strings.Join(ConfigRobotList, ","), v.ObjectName, v.WebHookName, v.WebHookAddress, v.Object,
					v.Object, time.Now(), time.Now())
				if err1 == nil {
					// 推送到飞书群聊
					statusCode, _, err := helper.Net{}.Request(context.Background(), "POST", v.WebHookAddress, nil,
						map[string]interface{}{
							"msg_type": "text",
							"content": map[string]interface{}{
								"text": excelURL,
							},
						},
					)
					if statusCode != 200 || err != nil {
						logx.Error(context.Background(), "空货周报推送error", logx.Any("statusCode", statusCode), logx.Any("error", err))
					} else {
						logx.Error(context.Background(), "空货周报推送success", logx.Any("statusCode", statusCode), logx.Any("error", err))
					}
				} else {
					logx.Error(context.Background(), "空货周报log写入error")
				}
			}
		}
	}
	return
}

// 生成上一日的所有机器的历史库存 -- 也包括省市商场位置及具体商品信息（所有有商户有商场的机器）
func SaveHistorySalesInfo() (err error) {
	// 默认获取所有机器上一日的库存信息
	db := mysql.NewDB()
	data, _, err := robotinfo.RobotInfoService{}.GetHistoryInventoryBySalesid(db)
	for k, v := range data {
		// 获取故障货道信息
		data[k].ErrorContainerNum, data[k].ZeroContainerNum, _ = robotinfo.RobotInfoService{}.GetHistoryErrorContainerNums(
			context.Background(), dal.Q, v.SalesID)

		var data2 []robotinfo.MaRobotSalesInfoDetail
		for _, v1 := range v.Data {
			if (v1.RobotGoodsInventory == 0 && v1.GoodsMaxInventory == 0) || v1.ContainerStatus == 0 {
				// 过滤已下架的商品
			} else {
				data2 = append(data2, v1)
			}
		}
		data[k].Areas3 = v.Data[0].Areas3
		if len(data2) > 0 {
			data[k].Data = data2
		}
	}
	// 写入数据库,包括商品库存信息
	var RobotInventoryList []models.MaRobotInventory
	for _, v := range data {
		// 写入商品的库存信息
		for _, v1 := range v.Data {
			var insert models.MaRobotInventory
			if v.Areas3 != "" && v.SalesID != "" && v.MerchantID != "" {
				Date := datatypes.Date(carbon.Yesterday().ToStdTime())
				insert.RobotName = v.RobotName
				insert.Date = Date
				insert.SalesID = v.SalesID
				insert.ShopID = v.MerchantID
				insert.Areas3 = v.Areas3
				insert.GoodsInventory = int64(v1.RobotGoodsInventory)
				insert.GoodsMaxInventory = int64(v1.GoodsMaxInventory)
				insert.GoodsID = int64(v1.GoodsID)
				insert.ErrorContainerNum = v.ErrorContainerNum
				insert.ZeroContainerNum = v.ZeroContainerNum // 累加0货道，逗号隔开
				RobotInventoryList = append(RobotInventoryList, insert)
			}
		}
	}
	// 写入数据库
	if len(RobotInventoryList) > 0 {
		db.Model(&models.MaRobotInventory{}).CreateInBatches(&RobotInventoryList, 10)
	}
	return err
}

// CreateEmptyStockExcel 生成空货excel
// @param stockType 1单日空货 2连续空货
func CreateEmptyStockExcel(stockData []EmptyStockStruct, stockType int) (url string) {
	var stockTypeStr string = ""
	if stockType == 1 {
		stockTypeStr = "单日空货"
	} else if stockType == 2 {
		stockTypeStr = "连续空货"
	}
	// 创建资源
	f := excelize.NewFile()
	defer func() {
		if err := f.Close(); err != nil {
			fmt.Println(err)
		}
	}()
	// 设置提醒的字体类型
	headStyle, _ := f.NewStyle(&excelize.Style{
		Font: &excelize.Font{
			Color:  "#FF0000",
			Bold:   true,
			Family: "宋体",
			Size:   14,
		},
	})
	contentStyle, _ := f.NewStyle(&excelize.Style{
		Font: &excelize.Font{
			Bold:   true,
			Family: "宋体",
			Size:   14,
		},
	})
	// 设置单元格样式
	f.SetColWidth("Sheet1", "A", "G", 20)            // 设置宽度
	f.SetCellStyle("Sheet1", "A", "G", contentStyle) // 内容的样式
	f.SetCellStyle("Sheet1", "A1", "A1", headStyle)  // 表头样式
	f.SetCellStyle("Sheet1", "B1", "B1", headStyle)
	f.SetCellStyle("Sheet1", "C1", "C1", headStyle)
	f.SetCellStyle("Sheet1", "D1", "D1", headStyle)
	f.SetCellStyle("Sheet1", "E1", "E1", headStyle)
	f.SetCellStyle("Sheet1", "F1", "F1", headStyle)
	f.SetCellStyle("Sheet1", "G1", "G1", headStyle)

	// 以数组方式实现excel数据的填充
	inputData := [][]interface{}{
		{"设备ID", "商品名称", "所在地区", "所在位置", "当前库存", "最大库存", "空货类型"},
	}
	for _, v := range stockData {
		inputData = append(inputData, []interface{}{
			v.RobotName,
			v.GoodsName1,
			v.ProvinceID + v.CityID,
			v.LocationID,
			v.GoodsInventory,
			v.GoodsMaxInventory,
			stockTypeStr,
		})
	}
	for idx, row := range inputData {
		cell, err := excelize.CoordinatesToCellName(1, idx+1)
		if err != nil {
			fmt.Println(err)
			return
		}
		// 数据写入
		f.SetSheetRow("Sheet1", cell, &row)
	}

	// 根据指定路径保存文件
	uuid, _ := helper.UUID{}.String()
	fileName := "/file/sale-admin/report_excel/" + uuid + "-" + carbon.Yesterday().StartOfDay().ToDateString()
	if err := f.SaveAs(fileName + ".xlsx"); err != nil {
		fmt.Println(err)
	}
	return config.Config.BaseUrl + fileName + ".xlsx"
}

// CreateWeekEmptyStockExcel 生成空货周报excel
func CreateWeekEmptyStockExcel(stockData []EmptyWeeklyReport) (url string) {
	Monday := carbon.Now().SubDays(7).ToShortDateString() // 20060102
	Tuesday := carbon.Now().SubDays(6).ToShortDateString()
	Wednesday := carbon.Now().SubDays(5).ToShortDateString()
	Thursday := carbon.Now().SubDays(4).ToShortDateString()
	Friday := carbon.Now().SubDays(3).ToShortDateString()
	Saturday := carbon.Now().SubDays(2).ToShortDateString()
	Sunday := carbon.Now().SubDays(1).ToShortDateString()
	// 创建资源
	f := excelize.NewFile()
	defer func() {
		if err := f.Close(); err != nil {
			fmt.Println(err)
		}
	}()
	// 设置提醒的字体类型
	headStyle, _ := f.NewStyle(&excelize.Style{
		Font: &excelize.Font{
			Color:  "#FF0000",
			Bold:   true,
			Family: "宋体",
			Size:   14,
		},
	})
	contentStyle, _ := f.NewStyle(&excelize.Style{
		Font: &excelize.Font{
			Bold:   true,
			Family: "宋体",
			Size:   14,
		},
	})
	// 设置单元格样式
	f.SetColWidth("Sheet1", "A", "G", 20)            // 设置宽度
	f.SetCellStyle("Sheet1", "A", "G", contentStyle) // 内容的样式
	f.SetCellStyle("Sheet1", "A1", "A1", headStyle)  // 表头样式
	f.SetCellStyle("Sheet1", "B1", "B1", headStyle)
	f.SetCellStyle("Sheet1", "C1", "C1", headStyle)
	f.SetCellStyle("Sheet1", "D1", "D1", headStyle)
	f.SetCellStyle("Sheet1", "E1", "E1", headStyle)
	f.SetCellStyle("Sheet1", "F1", "F1", headStyle)
	f.SetCellStyle("Sheet1", "G1", "G1", headStyle)
	f.SetCellStyle("Sheet1", "H1", "H1", headStyle)
	f.SetCellStyle("Sheet1", "I1", "I1", headStyle)
	f.SetCellStyle("Sheet1", "J1", "J1", headStyle)
	f.SetCellStyle("Sheet1", "K1", "K1", headStyle)
	f.SetCellStyle("Sheet1", "L1", "L1", headStyle)
	f.SetCellStyle("Sheet1", "M1", "M1", headStyle)

	// 以数组方式实现excel数据的填充
	inputData := [][]interface{}{
		{
			"设备ID", "商品名称", "所在地区", "所在位置", Monday, Tuesday, Wednesday, Thursday, Friday,
			Saturday, Sunday, "空货合计", "空货率",
		},
	}
	for _, v := range stockData {
		inputData = append(inputData, []interface{}{
			v.RobotName,
			v.GoodsName,
			v.Province + v.City,
			v.Location,
			v.Monday, v.Tuesday, v.Wednesday, v.Thursday, v.Friday, v.Saturday, v.Sunday,
			v.EmptyTotal,
			v.EmptyRate,
		})
	}
	for idx, row := range inputData {
		cell, err := excelize.CoordinatesToCellName(1, idx+1)
		if err != nil {
			fmt.Println(err)
			return
		}
		// 数据写入
		f.SetSheetRow("Sheet1", cell, &row)
	}

	// 根据指定路径保存文件
	uuid, _ := helper.UUID{}.String()
	fileName := "/file/sale-admin/report_excel/" + uuid + "-" + carbon.Now().ToDateString()
	if err := f.SaveAs(fileName + ".xlsx"); err != nil {
		fmt.Println(err)
	}
	return config.Config.BaseUrl + fileName + ".xlsx"
}
